React Native enhances mobile development in many ways, but it’s no big news that one of the the most talked about feature is its built-in ability to dynamically load the application code.
This opens new ways of developing and releasing applications (expecially for iOS) so that it naturally spawned services like AppHub and projects as CodePush.
AeroFS‘s guys are providing their addition to this kind of functionality providing it as an NPM Package for iOS and Android.

——Facebook ReactNative Official Introduction

前言

写在前面~

最近完成了Gank.io ReactNative 客户端1.0+版本的开发。近期也发现学习这个项目的同学还真不少,因此这个系列博客也就应运而生了,为的是帮助大家更好的学习和理解ReactNative的开发流程以及开发思路

系列大纲

按照我当初的开发进度来为大家讲解学习 ( 更新周期: per week )

  1. 历史列表的实现 ( ListView的使用 )
  2. 使用活动栈来导航整个App页面 ( Navigator的讲解 )
  3. 通过Gank接口来获取核心数据 ( Promise、fetch的使用介绍 )
  4. 为每次访问添加TimeOut、优化网络访问 ( Promise进阶)
  5. 上拉加载以及主页面欢迎动画实现的介绍 (Animated动画讲解)
  6. 欢迎界面与数据加载的并行控制 (待定)

用ListView来撸一个Gank.io的历史页

配置React-Native开发环境

这里不做详细介绍,秋哥的 这篇文章 可以带你飞 ~

(以下内容假设读者是一位Js编程者, 且尽量使用Facebook推荐的es6语法)

ListView的基本使用

  1. ####观摩一个页面的代码基本结构

    import React from 'react-native' // 用来导入一些组件
    let { // 定义一个名字空间抽取部分子组件(可选)
    AppRegistry,
    StyleSheet,
    Component
    ...
    } = React

    class History extends Component {
    constructor (props) { //用来初始化一些属性
    super(props)
    this.state = {...} // 与状态相关的属性
    }

    render () { // 页面渲染入口函数
    ...
    }
    }

    let styles = StyleSheet.create({ // 提供了一种类似于CSS的样式表
    ...
    })

    AppRegistry.registerComponent('History', () => History // 注册为整个项目入口
  2. ####导入ReactNative的ListView等几个核心组件
    只需要在名字空间中加入ListView即可。在这里你可以加入你所用 到的任何ReactNative组件,这里还需要用到以下几种:

    • TouchableHighlight 或者 TouchableOpacity: 顾名思义这是用来做一些点击反馈效果的控件
    • RefreshControl: 用来给ScrollView做下拉刷新的组件,谁让ListView也是继承自ScrollView来的呢~
    • Image: 图片组件
    • Text
  3. ####为ListView设置源数据

    constructor (props) { //用来初始化一些属性
    super(props)
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
    this.state = {
    dataSource: ds.cloneWithRows(this._getData())
    } // 与状态相关的属性
    }

    _getData(){
    let data=[]
    for(let i = 0; i < 20; i++){
    data.push({title: 'Gank.io', uri: 'http://ww2.sinaimg.cn/large/7a8aed7bjw1f0cw7swd9tj20hy0qogoo.jpg'})
    }
    return data
    }

    这里我们就不南辕北辙了,先用一些模拟数据做代替吧,这里给出的是一张我最喜欢的,哈哈。

    • var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 它的作用是监控每一行的数据,如果发现该行数据发生改变,则只重新渲染这一行
    • 然后我们使用ds变量调用cloneWithRows(...) 来为ListView提供数据,其参数是一个数组,这里我们使用了_getData()来生成模拟数据
  4. ####应用ListView组件

    render () {
    return (
    <View style={styles.container}>
    <ListView
    dataSource={this.state.dataSource}
    renderRow={this._renderItem.bind(this)}
    }/>
    </View>
    )
    }

    _renderItem (contentData, sectionID, highlightRow) {
    return (
    <TouchableHighlight>
    <View style={styles.itemContainer}>
    <Text style={[styles.title]}>{contentData.results.休息视频[0].desc}</Text>
    <Image source={{uri: contentData.results.福利[0].url}}
    style={styles.thumbnail}/>
    </View>
    </TouchableHighlight>
    )
    }

    var styles = StyleSheet.create({
    container: {
    flex: 1,
    backgroundColor: '#252528'
    },
    itemContainer: {
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    paddingTop: 20
    },
    thumbnail: {
    width: null, // 配合alignSelf实现宽度上match_parent
    height: 260,
    alignSelf: 'stretch'
    },
    title: {// alignSelf 默认是center
    fontSize: 15,
    marginBottom: 10,
    marginRight: 35,
    marginLeft: 35,
    // letterSpacing: 10,//字间距
    lineHeight: 22, // 行距+字高,0表示和字高一样,没效果
    color: 'white',
    textAlign: 'center' // 字的对其方式:center每行都居中;left,right;auto === justify === left
    }
    }

    这里使用了ReactNative所要求的JSX语法来实现。如上,ListView必要的属性就两个,dataSourcerenderRow

    • dataSource: 为ListView设置数据源
    • renderRow: 渲染每一行视图的回调方法
    • _renderItem(contentData, sectionID, highlightRow): 每一条视图的渲染,第一个参数表示当前条目的数据,与数据源的数组对应。
    • styles: 这里则是我们所用到的一些style样式

为ListView添加下拉刷新功能

这里我们需要介绍一下一个组件RefreshControl.
这是Facebook提供的专门为ScrollView组件添加下拉刷新功能的一个控件,而ScrollView也有refreshControl这个属性与之对应。

<ListView
dataSource={this.state.dataSource}
renderRow={this._renderItem.bind(this)}
refreshControl={
<RefreshControl
onRefresh={this._refresh.bind(this)}
tintColor='#aaaaaa'
title='Loading...'
progressBackgroundColor='#aaaaaa'/>}
/>

加完刷新控件之后,ListView成了以上这个样子。

  • _refresh()方法也是我们为onRefresh提供的回调方法。
    更新管理数据源以及使用setState()来调起render()的重任就交给它啦

  • refreshing RefreshControl也提供了这个属性用来控制下拉动画的状态。控制这个变量的bool值可以放在state属性中。我们可以在数据加载完毕后,通过setState来更改对应变量的属性。

运行效果

项目源码

以上部分代码已经放在 我的Github上,欢迎来访查看。

作者:poberWong
发布时间:2016-02-19 20:27
更新时间:2016-02-23 9:30
版权声明:自由转载 - 不可商用 - 不可衍生 - 保持署名 (请遵守:CreativeCommons 3.0协议)

donation